<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    /*
    Promise.then 方法用户注册状态改变回调函数的，该方法也返回一个Promise对象，
    1.若该方法中返回值类型不是Promise，则会自动封装为一个Promise对象，供链式调用；
    2.若该方法中返回值类型是Promise，则直接使用其作为then方法的返回值。
    3.不写return，等价于 return undefined，同1。
    */
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('data')
        }, 1000)
    })

    // 注册多个回调函数，状态改变时依次被调用，但是前后回调函数之间传递的值为具体return的值，
    // 若前一个回调函数没写return，后一个接收的参数就为undefined  
    p.then((data) => {
        console.log(data) // data 
        return 123 
    }).then(data => {
        console.log(data) // 123 
    }).then(data => {
        console.log(data) // undefined 
    })

    // then返回非Promise对象的情况，隐式返回的这个Promise和原始Promise是同一个对象吗？ 否，但二者状态相同 
    let p1 = p.then(() => {})
    console.log('p === p1 ?', p === p1) // false 
    console.log(p, p1)


    // then中返回Promise对象 
    // 虽然 data1、data2、data3 超时递减，但还是会按顺序回调打印 
    // 此方式可解决回调地狱 
    p.then(data => {
        console.log(data) // 
        return 'data1'
    }).then(data => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log(data) // data1 
                resolve('data2')
            }, 2000)
        })
    }).then(data => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log(data) // data2
                resolve('data3')
            }, 1000)
        })
    }).then(data => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log(data) // data3 
            }, 100)
        })
    })


</script>
</html>